DHTMLX Documentation

Custom excell creation - simple way

The purpose of excells

Excell stands for EXtended CELL and represents the cell editor in the grid.

The way the data will be stored|shown|edited in the grid is controlled by the column type.
Each column type refers to the related excell object:
    ro => eXcell_ro
    ed => eXcell_ed
    ...
While API allows to attach events and update settings to control some aspects of data rendering, the full control can be achieved only by customizing (or creating new one) excells.
In most cases it is enough to redefine some single method of excell to change the related behavior - the full list of excell methods is provided here.

Creating read-only excells (formatters)

Read-они only excells are pretty simple. They are only used to describe the way how the incoming data needs to be rendered.

function eXcell_ro(cell){                                    //excell name is defined here
    if (cell){                                                     //default pattern, just copy it
        this.cell = cell;
        this.grid = this.cell.parentNode.grid;
    }
    this.edit = function(){}                                //read-only cell doesn't have edit method
    this.isDisabled = function(){ return true; }      // the cell is read-only, that's why it is always in the disabled state
    this.setValue=function(val){
        this.setCValue(val);                                       //actual data processing may be placed here, for now we just set value as it is
    }
}
eXcell_ro.prototype = new eXcell;    // nest all other methods from base class

While this snippet contains about 10 lines of code, most of it may be copy-pasted. There are only two places that need to be adjusted according to your needs:


For example, the following code will create an excell which will render the cell value as button with a label:
function eXcell_button(cell){                                    //excell name is defined here
    if (cell){                                                     //default pattern, just copy it
        this.cell = cell;
        this.grid = this.cell.parentNode.grid;
    }
    this.edit = function(){}                                //read-only cell doesn't have edit method
    this.isDisabled = function(){ return true; }      // the cell is read-only, that's why it is always in the disabled state
    this.setValue=function(val){
        this.setCValue("<input type='button' value='"+val+"'>",val);                                     
    }
}
eXcell_button.prototype = new eXcell;    // nest all other methods from base class

As you can see, the above mentioned snippet differs from the previous one only in two places but now you can automatically convert the incoming data into a button just by defining the column type:

grid.setColTypes("button,ro");

You can use any kind of HTML in the process of cell code generation, which allows you to place complex elements inside the grid and style them as necessary. The code mentioned below creates a complex excell type, which will open new window with details on pressing the button:

function eXcell_details(cell){                             //excell name is defined here
    if (cell){                                                     //default pattern, just copy it
        this.cell = cell;
        this.grid = this.cell.parentNode.grid;
    }
    this.edit = function(){}                                //read-only cell doesn't have edit method
    this.isDisabled = function(){ return true; }      // the cell is read-only, that's why it is always in the disabled state
    this.setValue=function(val){

          var row_id=this.cell.parentNode.idd;     //get related row id

          this.setCValue(val+"<input type='button' onclick='window.open(\"details.php?for=\"+row_id)'>",val);                                     
    }
}
eXcell_button.prototype = new eXcell;    // nest all other methods from base class

Creating editable excells

The editable excells use the same approach, but with a few additional methods.
Lets analyze the simplest case:
function eXcell_button(cell){                             //excell name is defined here
    if (cell){                                                     //default pattern, just copy it
        this.cell = cell;
        this.grid = this.cell.parentNode.grid;
        eXcell_ed.call(this);                                //use methods of "ed" excell
    }
    this.setValue=function(val){
        this.setCValue("<input type='button' value='"+val+"'>",val); 
    }
    this.getValue=function(){
       return this.cell.firstChild.value; // get button label
    }
}
eXcell_button.prototype = new eXcell;    // nest all other methods from base class
As result - 3 new methods were added:
In spite of the fact that we have twice as much rows in this example as we had for read-only excell creation, basically we have only one row which needs to be customized. Both edit and detach events are fully reused from the already existing excell.

Editable button creation is pretty useless use case, so lets change it into something more usable:
function eXcell_myprice(cell){                                    //excell name is defined here
    if (cell){                                                     //default pattern, just copy it
        this.cell = cell;
        this.grid = this.cell.parentNode.grid;
        eXcell_ed.call(this);                                //use methods of "ed" excell
    }
    this.setValue=function(val){
        this.setCValue("<span>"+val+"</span><span> USD</span>",val);                                     
    }
    this.getValue=function(){
       return this.cell.childNodes[0].innerHTML; // get value
    }
}
eXcell_button.prototype = new eXcell;    // nest all other methods from base class
As you can see, only the text marked in bold was changed, and now, instead of a useless button we have the value formated with some postfix. This value can be correctly editable as Integer value.

In the most complex cases you may need to create an excell with custom editor. In such situation lets see the sample code of excell which can be used for hour selecting, instead of the simple text input. In addition to the default input, cell editor will have an additional time selector:

function eXcell_mytime(cell){                                    //excell name is defined here
    if (cell){                                                     //default pattern, just copy it
        this.cell = cell;
        this.grid = this.cell.parentNode.grid;
    }
    this.setValue=function(val){
        this.setCValue(val);                                     
    }
    this.getValue=function(){
       return this.cell.innerHTML; // get value
    }
    this.edit=function(){
        this.val = this.getValue(); //save current value
        this.cell.innerHTML="<input type='text' style='width:50px;'><select style='width:50px;'><option value='AM'>AM<option value='PM'>PM</select>"; // editor's html
        this.cell.firstChild.value=parseInt(val); //set the first part of data
        if (val.indexOf("PM")!=-1) this.cell.childNodes[1].value="PM";

          this.cell.childNodes[0].onclick=function(e){ (e||event).cancelBubble=true; } //block onclick event
          this.cell.childNodes[1].onclick=function(e){ (e||event).cancelBubble=true; } //block onclick event
    }
    this.detach=function(){
        this.setValue(this.cell.childNodes[0].value+" "+this.cell.childNodes[1].value); //set the new value
        return this.val!=this.getValue();    // compare the new and the old values
    }
}
eXcell_button.prototype = new eXcell;    // nest all other methods from base class

As you can see this sample contains some additional code, but there is still nothing really complex.
HTML code of editor is defined inside "edit" method, thus the editor is filled with current values.
Values from the editor are combined to get a new cell value inside "detach" method.